﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.ComponentModel;


namespace BizElements.BusinessLayer
{
    /// <summary>
    /// Contains commonly used generic procedure and function delegates.
    /// </summary>
    public static class Delegates
    {
        #region Procedures.

        /// <summary>
        /// Represents a parameterless method that doesn't return a value.
        /// </summary>
        public delegate void Procedure();

        /// <summary>
        /// Represents a method that accepts one argument and doesn't return a value.
        /// </summary>
        /// <typeparam name="TArg">Argument type.</typeparam>
        /// <param name="arg">Method argument.</param>
        public delegate void Procedure<TArg>(TArg arg);

        /// <summary>
        /// Represents a method that accepts two arguments and doesn't return a value.
        /// </summary>
        /// <typeparam name="TArg1">Type of the first argument.</typeparam>
        /// <typeparam name="TArg2">Type of the second argument.</typeparam>
        /// <param name="arg1">First argument.</param>
        /// <param name="arg2">Second argument.</param>
        public delegate void Procedure<TArg1, TArg2>(TArg1 arg1, TArg2 arg2);

        /// <summary>
        /// Represents a method that accepts three arguments and doesn't return a value.
        /// </summary>
        /// <typeparam name="TArg1">Type of the first argument.</typeparam>
        /// <typeparam name="TArg2">Type of the second argument.</typeparam>
        /// <typeparam name="TArg3">Type of the third argument.</typeparam>
        /// <param name="arg1">First argument.</param>
        /// <param name="arg2">Second argument.</param>
        /// <param name="arg3">Third argument.</param>
        public delegate void Procedure<TArg1, TArg2, TArg3>(TArg1 arg1, TArg2 arg2, TArg3 arg3);

        /// <summary>
        /// Represents a method that accepts four arguments and doesn't return a value.
        /// </summary>
        /// <typeparam name="TArg1">Type of the first argument.</typeparam>
        /// <typeparam name="TArg2">Type of the second argument.</typeparam>
        /// <typeparam name="TArg3">Type of the third argument.</typeparam>
        /// <typeparam name="TArg4">Type of the fourth argument.</typeparam>
        /// <param name="arg1">First argument.</param>
        /// <param name="arg2">Second argument.</param>
        /// <param name="arg3">Third argument.</param>
        /// <param name="arg4">Fourth argument.</param>
        public delegate void Procedure<TArg1, TArg2, TArg3, TArg4>(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4);

        /// <summary>
        /// Represents a method that accepts five arguments and doesn't return a value.
        /// </summary>
        /// <typeparam name="TArg1">Type of the first argument.</typeparam>
        /// <typeparam name="TArg2">Type of the second argument.</typeparam>
        /// <typeparam name="TArg3">Type of the third argument.</typeparam>
        /// <typeparam name="TArg4">Type of the fourth argument.</typeparam>
        /// <typeparam name="TArg5">Type of the fifth argument.</typeparam>
        /// <param name="arg1">First argument.</param>
        /// <param name="arg2">Second argument.</param>
        /// <param name="arg3">Third argument.</param>
        /// <param name="arg4">Fourth argument.</param>
        /// <param name="arg5">Fifth argument.</param>
        public delegate void Procedure<TArg1, TArg2, TArg3, TArg4, TArg5>(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5);

        #endregion

        #region Functions.

        /// <summary>
        /// Represents a parameterless method that returns a value of the specified type.
        /// </summary>
        /// <typeparam name="TRetVal">Type of the return value.</typeparam>
        /// <returns>A value of the specified type.</returns>
        public delegate TRetVal Function<TRetVal>();

        /// <summary>
        /// Represents a method that accepts one argument and returns a value of the specified type.
        /// </summary>
        /// <typeparam name="TRetVal">Type of the return value.</typeparam>
        /// <typeparam name="TArg">Argument type.</typeparam>
        /// <param name="arg">Method argument.</param>
        /// <returns>A value of the specified type.</returns>
        public delegate TRetVal Function<TRetVal, TArg>(TArg arg);

        /// <summary>
        /// Represents a method that accepts two arguments and returns a value of the specified type.
        /// </summary>
        /// <typeparam name="TRetVal">Type of the return value.</typeparam>
        /// <typeparam name="TArg1">Type of the first argument.</typeparam>
        /// <typeparam name="TArg2">Type of the second argument.</typeparam>
        /// <param name="arg1">First argument.</param>
        /// <param name="arg2">Second argument.</param>
        /// <returns>A value of the specified type.</returns>
        public delegate TRetVal Function<TRetVal, TArg1, TArg2>(TArg1 arg1, TArg2 arg2);

        /// <summary>
        /// Represents a method that accepts three arguments and returns a value of the specified type.
        /// </summary>
        /// <typeparam name="TRetVal">Type of the return value.</typeparam>
        /// <typeparam name="TArg1">Type of the first argument.</typeparam>
        /// <typeparam name="TArg2">Type of the second argument.</typeparam>
        /// <typeparam name="TArg3">Type of the third argument.</typeparam>
        /// <param name="arg1">First argument.</param>
        /// <param name="arg2">Second argument.</param>
        /// <param name="arg3">Third argument.</param>
        /// <returns>A value of the specified type.</returns>
        public delegate TRetVal Function<TRetVal, TArg1, TArg2, TArg3>(TArg1 arg1, TArg2 arg2, TArg3 arg3);

        /// <summary>
        /// Represents a method that accepts four arguments and returns a value of the specified type.
        /// </summary>
        /// <typeparam name="TRetVal">Type of the return value.</typeparam>
        /// <typeparam name="TArg1">Type of the first argument.</typeparam>
        /// <typeparam name="TArg2">Type of the second argument.</typeparam>
        /// <typeparam name="TArg3">Type of the third argument.</typeparam>
        /// <typeparam name="TArg4">Type of the fourh argument.</typeparam>
        /// <param name="arg1">First argument.</param>
        /// <param name="arg2">Second argument.</param>
        /// <param name="arg3">Third argument.</param>
        /// <param name="arg4">Fourth argument.</param>
        /// <returns>A value of the specified type.</returns>
        public delegate TRetVal Function<TRetVal, TArg1, TArg2, TArg3, TArg4>(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4);

        /// <summary>
        /// Represents a method that accepts five arguments and returns a value of the specified type.
        /// </summary>
        /// <typeparam name="TRetVal">Type of the return value.</typeparam>
        /// <typeparam name="TArg1">Type of the first argument.</typeparam>
        /// <typeparam name="TArg2">Type of the second argument.</typeparam>
        /// <typeparam name="TArg3">Type of the third argument.</typeparam>
        /// <typeparam name="TArg4">Type of the fourth argument.</typeparam>
        /// <typeparam name="TArg5">Type of the fifth argument.</typeparam>
        /// <param name="arg1">First argument.</param>
        /// <param name="arg2">Second argument.</param>
        /// <param name="arg3">Third argument.</param>
        /// <param name="arg4">Fourth argument.</param>
        /// <param name="arg5">Fifth argument.</param>
        /// <returns>A value of the specified type.</returns>
        public delegate TRetVal Function<TRetVal, TArg1, TArg2, TArg3, TArg4, TArg5>(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5);

        #endregion
    }
}